package cn.rwklyd.BookKeeping.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.rwklyd.BookKeeping.constant.MessageConstant;
import cn.rwklyd.BookKeeping.mapper.mybatisPlus.AdminMapper_Mp;
import cn.rwklyd.BookKeeping.pojo.dto.LoginData;
import cn.rwklyd.BookKeeping.pojo.dto.RegisterRequest;
import cn.rwklyd.BookKeeping.pojo.vo.LoginUser;
import cn.rwklyd.BookKeeping.service.SystemService;
import cn.rwklyd.BookKeeping.pojo.Result;
import cn.rwklyd.BookKeeping.pojo.User;
import cn.rwklyd.BookKeeping.service.VerificationCodeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import cn.rwklyd.BookKeeping.service.TokenService;

@RestController
@RequestMapping("/system")
@Tag(name = "系统管理", description = "系统管理相关接口,开放接口")
@Slf4j
public class SystemController {

    @Autowired
    private SystemService systemService;
    @Autowired
    private AdminMapper_Mp adminMapper_mp;
    @Autowired
    private VerificationCodeService verificationCodeService;
    @Autowired
    private TokenService tokenService;

    @PostMapping("/login")
    @Operation(summary = "登录接口", description = "登录接口")
    public Result<Map<String, Object>> login(@RequestBody LoginData loginData){
        if (loginData.getUsername() == null || loginData.getUsername().trim().isEmpty()) {
            return Result.error(MessageConstant.USERNAME_NOT_EMPTY);
        } else if (loginData.getPassword() == null || loginData.getPassword().trim().isEmpty()) {
            return Result.error(MessageConstant.PASSWORD_NOT_EMPTY);
        }

//         验证 Turnstile 令牌
      /*  if (!systemService.verifyTurnstile(loginData.getTurnstileToken())) {
            return Result.error("Turnstile验证失败");
        }*/

        // 第一步：进行登录验证
        User user = new User();
        BeanUtils.copyProperties(loginData, user);
        Map<String, Object> responseData = systemService.Login(user);
        return Result.success(responseData);
    }

    @PostMapping("/logOut")
    @Operation(summary = "登出接口", description = "注销接口")
    public Result<String> logOut(HttpServletRequest request, HttpServletResponse response){
        String token = request.getHeader("Authorization");
        // 如果token拿不到就从传输中获取
        if(ObjectUtil.isEmpty(token)){
            token = request.getParameter("Authorization");
        }
        
        // 获取用户相关信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(ObjectUtil.isNotEmpty(authentication)){
            // 清空用户信息
            new SecurityContextLogoutHandler().logout(request, response, authentication);
            
            // 获取当前用户ID
            if (authentication.getPrincipal() instanceof LoginUser) {
                LoginUser loginUser = (LoginUser) authentication.getPrincipal();
                User user = loginUser.getUser();
                Integer userId = user.getId();
                
                // 使刷新令牌失效
                try {
                    tokenService.invalidateRefreshToken(userId);
                    log.info("已成功使用户 {} 的刷新令牌失效", userId);
                } catch (Exception e) {
                    log.error("使刷新令牌失效时出错", e);
                }
            }
        }
        return Result.success(MessageConstant.LOGOUT_SUCCESS);
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    @Operation(summary = "注册接口", description = "用户注册接口")
    public Result<String> register(@RequestBody RegisterRequest registerRequest) {
        String username = registerRequest.getUsername();
        String password = registerRequest.getPassword();
        String email = registerRequest.getEmail();
        String code = registerRequest.getCode();

        // 参数验证
        if (username == null || password == null || email == null || code == null) {
            return Result.error("参数不完整");
        }

        try {
            // 验证邮箱验证码
            boolean codeVerified = verificationCodeService.verifyCode(email, code, "register");
            if (!codeVerified) {
                return Result.error("验证码错误或已过期");
            }

            // 添加这个检查，确保当前提交的邮箱与之前验证的邮箱一致
            boolean emailVerified = verificationCodeService.checkEmailVerified(email, code, "register");
            if (!emailVerified) {
                return Result.error("邮箱已被修改，请重新获取验证码");
            }

            // 检查用户名是否已存在
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getUsername, username);
            if (adminMapper_mp.selectCount(queryWrapper) > 0) {
                return Result.error(MessageConstant.USERNAME_ALREADY_EXISTS);
            }

            // 检查邮箱是否已存在
            LambdaQueryWrapper<User> emailWrapper = new LambdaQueryWrapper<>();
            emailWrapper.eq(User::getEmail, email);
            if (adminMapper_mp.selectCount(emailWrapper) > 0) {
                return Result.error(MessageConstant.EMAIL_ALREADY_EXISTS);
            }

            // 创建用户对象
            User user = new User();
            user.setUsername(username);
            user.setEmail(email);

            // 对密码进行加密处理
            PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            String encodedPassword = passwordEncoder.encode(password);
            user.setPassword(encodedPassword);

            // 插入用户
            adminMapper_mp.insert(user);

            // 注册成功后清除邮箱验证状态
            verificationCodeService.clearEmailVerification(email, "register");

            return Result.success(MessageConstant.REGISTER_SUCCESS);
        } catch (Exception e) {
            return Result.error("REGISTER_FAILED: " + e.getMessage());
        }
    }


    /**
     * 发送邮箱验证码
     */
    @PostMapping("/sendEmailCode")
    @Operation(summary = "发送邮箱验证码", description = "发送邮箱验证码")
    @PreAuthorize("permitAll()")
    public Result<String> sendEmailCode(@RequestBody Map<String, String> params) {
        String email = params.get("email");
        String type = params.get("type");

        if (email == null || email.isEmpty()) {
            return Result.error(MessageConstant.EMAIL_CANNOT_BE_EMPTY);
        }

        // 邮箱格式验证
        if (!email.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")) {
            return Result.error(MessageConstant.EMAIL_FORMAT_ERROR);
        }

        // 如果是注册，检查邮箱是否已被注册
        if ("register".equals(type)) {
            LambdaQueryWrapper<User> emailWrapper = new LambdaQueryWrapper<>();
            emailWrapper.eq(User::getEmail, email);
            if (adminMapper_mp.selectCount(emailWrapper) > 0) {
                return Result.error(MessageConstant.EMAIL_ALREADY_EXISTS);
            }
        }

        try {
            boolean success = verificationCodeService.sendCode(email, type);
            if (success) {
                return Result.success(MessageConstant.Code_SEND_SUCCESS);
            } else {
                return Result.error(MessageConstant.Code_SEND_FAILURE + "请稍后重试");
            }
        } catch (Exception e) {
            return Result.error(MessageConstant.Code_SEND_FAILURE + e.getMessage());
        }
    }

}
